package com.wys.spring.swagger;

import com.alibaba.nacos.common.utils.IPUtil;
import com.github.xiaoymin.knife4j.spring.extension.OpenApiExtensionResolver;
import com.wys.spring.SpringCommonProperties;
import com.wys.spring.swagger.plugin.*;
import io.swagger.annotations.Api;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.builders.RequestParameterBuilder;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.service.RequestParameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

import java.util.ArrayList;
import java.util.List;

public class SwaggerConfig {

    @Bean
    NotNullParameterBuilderPlugin notNullParameterBuilderPlugin() {
        return new NotNullParameterBuilderPlugin();
    }

    @Bean
    NotNullModelPropertyBuilderPlugin notNullModelPropertyBuilderPlugin() {
        return new NotNullModelPropertyBuilderPlugin();
    }

    @Bean
    NotBlankModelPropertyBuilderPlugin notBlankModelPropertyBuilder() {
        return new NotBlankModelPropertyBuilderPlugin();
    }

    @Bean
    @ConditionalOnMissingBean
    public DynamicParamBuilderPlugin dynamicParamBuilderPlugin(SpringCommonProperties springCommonProperties) {
        return new DynamicParamBuilderPlugin(springCommonProperties);
    }

    @Bean
    NotBlankParameterBuilderPlugin notBlankParameterBuilderPlugin() {
        return new NotBlankParameterBuilderPlugin();
    }


    @Bean
    @ConditionalOnMissingBean
    Docket docket(SpringCommonProperties springCommonProperties, OpenApiExtensionResolver openApiExtensionResolver) {
        Docket docket = new Docket((springCommonProperties != null && ObjectUtils.isNotEmpty(springCommonProperties.getSwagger())) ? springCommonProperties.getSwagger().getDocumentationType().getDocumentationType() : DocumentationType.SWAGGER_2);
        List<RequestParameter> requestParameters = new ArrayList<>();
        if (ObjectUtils.isNotEmpty(springCommonProperties.getSwagger()) && ObjectUtils.isNotEmpty(springCommonProperties.getSwagger().getRequestParameters())) {
            springCommonProperties.getSwagger().getRequestParameters().forEach(s -> {
                requestParameters.add(new RequestParameterBuilder().in(s.getIn()).parameterIndex(s.getParameterIndex())
                        .hidden(s.getHidden()).description(s.getDescription()).name(s.getName())
                        .deprecated(s.getDeprecated()).required(s.getRequired()).build());
            });
        }
        if(ObjectUtils.isNotEmpty(springCommonProperties.getSwagger())){
            ApiInfo apiInfo = ObjectUtils.isNotEmpty(springCommonProperties.getSwagger().getApiInfo()) ? new ApiInfoBuilder().description(springCommonProperties.getSwagger().getApiInfo().getDescription())
                    .contact(new Contact("sunnykaka", "sunnykaka", "1977988429@qq.com"))
                    .title(springCommonProperties.getSwagger().getApiInfo().getTitle())
                    .version(springCommonProperties.getSwagger().getApiInfo().getVersion()).build() : ApiInfo.DEFAULT;
            docket.apiInfo(apiInfo)
                    .enable(true)
                    .select()
                    .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
                    .paths(PathSelectors.any())
                    .build().globalRequestParameters(requestParameters)
                    .groupName(springCommonProperties.getSwagger().getGroupName())
                    .extensions(openApiExtensionResolver.buildSettingExtensions())
                    .host(IPUtil.localHostIP());
        }
        return docket;
    }


}
